'use strict'

var Promise = require('bluebird');
var request = require('request');
var util = require('./util');
var config = require('../config').wechat;
var bathPath = "https://api.weixin.qq.com/cgi-bin/";
var api = {
	access_token: bathPath + 'token?grant_type=client_credential',
	ticket: {
		get: bathPath + 'ticket/getticket?'
	},
	oauth2: {
		getCode: "https://open.weixin.qq.com/connect/oauth2/authorize",
		access_token: "https://api.weixin.qq.com/sns/oauth2/access_token",
		user_info: "https://api.weixin.qq.com/sns/userinfo"
	}
}
// 构造函数
function Wechat(opts) {
	var that = this;
	this.appId = opts.appId;
	this.appSecret = opts.appSecret;
	this.getAccessToken = opts.getAccessToken;
	this.saveAccessToken = opts.saveAccessToken;
	// 更新并获取accessToken
	this.getTicket = opts.getTicket;
	this.saveTicket = opts.saveTicket;
	this.fetchAccessToken();
}



Wechat.prototype.isValidAccessToken = function (data) {
	if (!data || !data.access_token || !data.expires_in) {
		return false;
	}

	var access_token = data.access_token;
	var expires_in = data.expires_in;
	var now = (new Date().getTime())

	if (now < expires_in) {
		console.log("校验token成功");
		return true;
	} else {
		console.log("校验token失败");
		return false;
	}
}
Wechat.prototype.updateAccessToken = function () {
	var appId = this.appId;
	var appSecret = this.appSecret;
	var url = api.access_token + "&appid=" + appId + "&secret=" + appSecret;

	return new Promise(function (resolve, reject) {
		request(url, function (error, response, body) {
			if (!error && response.statusCode == 200) {
				var data = JSON.parse(body);
				var now = (new Date().getTime())
				var expires_in = now + (data.expires_in - 20) * 1000;

				data.expires_in = expires_in
				resolve(data)
				console.log('----updateAccessToken---' + data);
			}
		})

	})
}
// 更新获取基础access_token
Wechat.prototype.fetchAccessToken = function (data) {
	var that = this;
	return this.getAccessToken()
		.then(function (data) {
			// console.log('正在获取token：'+data);
			try {
				data = JSON.parse(data)
			} catch (e) {
				return that.updateAccessToken(data)
			}

			if (that.isValidAccessToken(data)) {
				return Promise.resolve(data)
			} else {
				console.log("token 失效，重新校验");
				return that.updateAccessToken();
			}
		}).then(function (data) {
			console.log("复制token：" + JSON.stringify(data));
			that.saveAccessToken(data);
			return Promise.resolve(data);
		})
}


// 进行用户授权
Wechat.prototype.doAuth = function (redirectUrl = '/redirect', state = '111') {
	this.session.redirect = this.href; //TODO: 这里可能获取不到
	return new Promise((resolve, reject) => {
		const params = {
			appid: config.appId,
			redirect_uri: redirectUrl,
			response_type: 'code',
			scope: "snsapi_userinfo",
			state: state + '#wechat_redirect'
		}
		const url = util.toUrl(api.oauth2.getCode, params);
		this.redirect(url);
	})
}

Wechat.prototype.getWebToken = function (ctx) {
	// 1. 获取微信返回来的code
	const { code, state } = ctx.query;
	const params = {
		appid: config.appId,
		secret: config.appSecret,
		code: code,
		grant_type: 'authorization_code'
	};
	const url = util.toUrl(api.oauth2.access_token, params);
	return new Promise((resolve, reject) => {
		request(url, function (error, response, body) {
			if (!error && response.statusCode == 200) {
				const { appId } = config;
				const data = JSON.parse(body);
				const { access_token, expires_in, refresh_token, openid, scope } = data;
				ctx.session.auth = { ...data, appId };
				resolve(data);
			}
		});

	})
}
Wechat.prototype.userInfo = function (data) {
	const { access_token, openid } = data;
	const params = {
		access_token: access_token,
		openid: openid
	};
	const url = util.toUrl(api.oauth2.user_info, params);
	return new Promise((resolve, reject) => {
		request(url, function (error, response, body) {
			if (!error && response.statusCode == 200) {
				const data = JSON.parse(body);
				resolve(data);
			}
		});

	})
}

//获取网页授权票据
Wechat.prototype.fetchTicket = function (access_token) {
	var that = this;
	return new Promise((resolve, reject) => {
		this.getTicket()
			.then(function (data) {
				try {
					data = JSON.parse(data)
				} catch (e) {
					return that.updateTicket(access_token)
				}

				if (that.isValidTicket(data)) {
					resolve(data)
				} else {
					console.log("ticket 失效，重新校验");
					return that.updateTicket(access_token);
				}
			}).then(function (data) {
				console.log("复制ticket：" + JSON.stringify(data));

				that.saveTicket(data);
				resolve(data);
			})
	})
}
Wechat.prototype.isValidTicket = function (data) {
	if (!data || !data.ticket || !data.expires_in) {
		return false;
	}

	var ticket = data.ticket;
	var expires_in = data.expires_in;
	var now = (new Date().getTime())

	if (ticket && now < expires_in) {
		console.log("校验ticket成功");
		return true;
	} else {
		console.log("校验ticket失败");
		return false;
	}
}
Wechat.prototype.updateTicket = function (access_token) {
	var appId = this.appId;
	var appSecret = this.appSecret;
	var url = api.ticket.get + "&access_token=" + access_token + '&type=jsapi';
	return new Promise(function (resolve, reject) {
		request(url, function (error, response, body) {
			if (!error && response.statusCode == 200) {
				var data = JSON.parse(body);
				var now = (new Date().getTime())
				var expires_in = now + (data.expires_in - 20) * 1000;

				data.expires_in = expires_in
				console.log("【update ticket】", JSON.stringify(data))
				resolve(data)
			}
		})

	})
}
module.exports = Wechat;